#ifndef PARSER_ATTRIBUTES_H_
#define PARSER_ATTRIBUTES_H_

#include <map>
#include <string>

namespace fermat {
namespace parser {

/**************************************************************
* This class stores attributes for a symbol table entry.
* Attributes are simple name-value pairs, where both
* name and values are strings.
***************************************************************/
class  Attributes {
public:
	static std::string kNotExist;
	typedef std::map<std::string, std::string> AttrMap;
	typedef AttrMap::const_iterator Iterator;
	
	/**************************************************************
	* Creates the Attributes object.
	***************************************************************/
	Attributes();
		
	/**************************************************************
	* Creates the Attributes object by copying another one.
	***************************************************************/
	Attributes(const Attributes& attrs);

	/**************************************************************
	* Destroys the Attributes object.
	***************************************************************/
	~Attributes();

	/**************************************************************
	* Assignment operator.
	***************************************************************/
	Attributes& operator = (const Attributes& attrs);

	/**************************************************************
	* @return true if an attribute with the given name exists.
	***************************************************************/		
	bool has(const std::string& name) const;

	/**************************************************************
	* @return the attribute's value as a string.
	***************************************************************/		
	std::string getString(const std::string& name) const;
		
	/**************************************************************
	* @return the attribute's value as a string, if it exists.
	* returns the defaultValue if the attribute does not exist.
	***************************************************************/
	std::string getString(const std::string& name, const std::string& defaultValue) const;

	/**************************************************************
	* Returns the attribute's value as an integer.
	***************************************************************/
	int getInt(const std::string& name) const;

	/**************************************************************
	* Returns the attribute's value as an integer, if it exists.
	* Returns the defaultValue if the attribute does not exist.
	***************************************************************/	
	int getInt(const std::string& name, int defaultValue) const;

	/**************************************************************
	* Returns the attribute's value as a boolean.
	* The returned value is 'true', iff the stored value is not "false".
	***************************************************************/
	bool getBool(const std::string& name) const;

	/**************************************************************
	*Returns the attribute's value as a boolean, if it exists.
	* The returned value is 'true', iff the stored value is not "false".
	***************************************************************/
	bool getBool(const std::string& name, bool defaultValue) const;

	/**************************************************************
	* Sets the value of an attribute.
	***************************************************************/
	void set(const std::string& name, const std::string& value);
		
	/**************************************************************
	*  Removes the attribute with the given name.
	* Does nothing if the attribute does not exist.
	***************************************************************/
	void remove(const std::string& name);

		
	const std::string& operator [] (const std::string& name) const;
	std::string& operator [] (const std::string& name);		
		
	Iterator begin() const;
	Iterator end() const;
	
	/**************************************************************
	* clear all the attributes
	***************************************************************/
	void clear();

private:
	AttrMap _map;
};


//
// inlines
//
inline Attributes::Iterator Attributes::begin() const
{
	return _map.begin();
}


inline Attributes::Iterator Attributes::end() const
{
	return _map.end();
}


} 
} 

#endif 
